﻿<%@ Page CodePage="65001" Language="C#" debug=true%>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Data" %>
<%--  変更のテスト２ --%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Small Board</title>
    <style type="text/css">
    .small {font-size:small; color:Gray;}
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <asp:HiddenField ID="hfID" runat="server" ></asp:HiddenField>
    <asp:HiddenField ID="hfCagegory" runat="server" ></asp:HiddenField>
    <div class="small" style="text-align:right;">Small Board</div>
    <h1><asp:Literal runat="server" ID="lPageTitle"></asp:Literal></h1>
    <asp:MultiView runat="server" ID="mvMain" ActiveViewIndex="0">
        <%-- 表示 --%>
        <asp:View runat="server" ID="vShow">
            <asp:LinkButton runat="server" ID="lbAddData" OnClick="OnClickAddData" Text="新規投稿"></asp:LinkButton>
            <div style="float:right;">
            </div>
            <hr />
            <b><asp:Literal runat="server" ID="lDataTitle" ></asp:Literal></b>
            <div class="small">
            <asp:Literal runat="server" ID="lDataName"></asp:Literal>
            <asp:Literal runat="server" ID="lDataDate"></asp:Literal>
            <asp:LinkButton runat="server" ID="lbDataEdit" OnCommand="OnClickEdit" Text="編集"></asp:LinkButton>
            </div>
            <p><asp:Literal runat="server" ID="lDataContent"></asp:Literal></p>
            <hr />
            <b>投稿INDEX</b>
            <div>
                <ul>
                <asp:Repeater runat="server" ID="repCategory">
                    <ItemTemplate>
<%-- ######################################################################
        タイトルを表示してるつもり  【ID - タイトル】　みたいなイメージで
     ###################################################################### --%>
                    <li><%# DataBinder.Eval(Container.DataItem, "Id") %>
                    	&nbsp;-&nbsp;
                        <%# DataBinder.Eval(Container.DataItem, "Title") %>
                        <asp:LinkButton ID="hlCategory" runat="server"
                            Text='表示'
                            OnCommand="OnClickView"
                            CommandArgument='<%# DataBinder.Eval(Container.DataItem, "Url") %>'>
                        </asp:LinkButton>
<%--                        <asp:LinkButton ID="LinkButton1" runat="server"
                            Text='編集'
                            OnCommand="OnClickEdit"
                            CommandArgument='<%# DataBinder.Eval(Container.DataItem, "Url") %>'>
                        </asp:LinkButton>
--%>                        <asp:Literal ID="lCategory" runat="server"></asp:Literal>
                    </li>
                    </ItemTemplate>
                </asp:Repeater>
                </ul>
            </div>
        </asp:View>
        
        
        <%-- 編集 --%>
        <asp:View runat="server" ID="vWrite">
            <asp:Label ID="lblTbTitle" runat="server" AssociatedControlID="tbTitle">タイトル</asp:Label>
            <br />
            <asp:TextBox ID="tbTitle" runat="server" ></asp:TextBox>
            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" 
                ControlToValidate="tbTitle" ValidationGroup="WriteGroup" Display="Dynamic"
                ErrorMessage="タイトルを入力してください"></asp:RequiredFieldValidator>
            <br />
            <asp:Label ID="lblTbName" runat="server" AssociatedControlID="tbName">名前</asp:Label>
            <br />
            <asp:TextBox ID="tbName" runat="server" ></asp:TextBox>
            <asp:RequiredFieldValidator ID="rfvTbName" runat="server" 
                ControlToValidate="tbName" ValidationGroup="WriteGroup" Display="Dynamic"
                ErrorMessage="名前を入力してください"></asp:RequiredFieldValidator>
            <br />
            <asp:Label ID="lblTbPassword" runat="server" AssociatedControlID="tbPassword">パスワード</asp:Label>
            <br />
            <asp:TextBox ID="tbPassword" runat="server" TextMode="Password" ></asp:TextBox>
            <asp:RequiredFieldValidator ID="rfvTbPassword" runat="server" 
                ControlToValidate="tbPassword" ValidationGroup="WriteGroup" Display="Dynamic"
                ErrorMessage="パスワードを入力してください"></asp:RequiredFieldValidator>
            <br />
            <asp:Label ID="lblTbContent" runat="server" AssociatedControlID="tbContent">内容</asp:Label>
            <br />
            <asp:TextBox ID="tbContent" runat="server" Rows="6" TextMode="MultiLine"></asp:TextBox>
            <asp:RequiredFieldValidator ID="rfvTbContent" runat="server" 
                ControlToValidate="tbContent" ValidationGroup="WriteGroup" Display="Dynamic"
                ErrorMessage="内容を入力してください"></asp:RequiredFieldValidator>
            <div class="small">
            作成:
            <asp:Literal ID="lCreateDate" runat="server"></asp:Literal>
            (from <asp:Literal ID="lCreateIP" runat="server"></asp:Literal>)
            <br />
            更新:
            <asp:Literal ID="lUpdateDate" runat="server"></asp:Literal>
            (from <asp:Literal ID="lUpdateIP" runat="server"></asp:Literal>)
            <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server"
                 ControlToValidate="tbContent" ValidationGroup="WriteGroup" Display="Dynamic"
                ErrorMessage="内容を入力してください"></asp:RequiredFieldValidator>
            </div>
            <br />
            <asp:Button ID="bCreateData" runat="server" Text="保存" OnClick="OnClickCreateData" ValidationGroup="WriteGroup" UseSubmitBehavior="true"/>
            <asp:Button ID="bCancel" runat="server" Text="キャンセル" OnClick="OnClickCancel" />
        </asp:View>
        
        <%-- 認証 --%>
        <asp:View runat="server" ID="vAuth">
            <p>パスワードを入力して、認証ボタンを押してください。</p>
            <asp:Label runat="server" ID="lblTbAuthPass" AssociatedControlID="tbAuthPass">パスワード:</asp:Label>
            <asp:TextBox runat="server" ID="tbAuthPass" TextMode="Password"></asp:TextBox>
            <asp:RequiredFieldValidator runat="server" ID="rfvTblAuthPass" ControlToValidate="tbAuthPass" Display="Dynamic" ValidationGroup="vgAuth">
                <br />パスワードを入力してください
            </asp:RequiredFieldValidator>
            <br />
            <asp:Button runat="server" ID="btnAuth" Text="認証" ValidationGroup="vgAuth" OnClick="OnClickAuth" />
            <p style="color:Red;">
                <asp:Literal runat="server" ID="lAuthMessage"></asp:Literal>
            </p>
            <br />
            <a href="default.aspx">戻る</a>
        </asp:View>
    </asp:MultiView>
    </form>
</body>
</html>
<script runat="server" type="text/C#">
    /// <summary> 投稿ID桁数 </summary>
    static string START_ID = "0000";
    /// <summary> データ保存ディレクトリ </summary>
    private string dataDirPath ="";
    static string ITEM_EXT = ".item";
    private static string CATEGORY_EXT = ".category";
    void Page_Load(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(dataDirPath))
        {
            string requestPath = Server.MapPath(Request.Path.Substring(0, Request.Path.LastIndexOf("/") + 1));
            dataDirPath = requestPath + "Data";
        }
            
        if (!Page.IsPostBack)
        {
            if (!Directory.Exists(dataDirPath))
            {
                Directory.CreateDirectory(dataDirPath);
            }

            ShowList(dataDirPath);
        }
    }
    /// <summary>
    /// 一覧表示
    /// </summary>
    /// <param name="dataDirpath"></param>
    private void ShowList(string dataDirpath)
    {
        lPageTitle.Text = "投稿一覧";
        DirectoryInfo info = new DirectoryInfo(dataDirpath);
        FileInfo[] items = info.GetFiles("*" + ITEM_EXT, SearchOption.TopDirectoryOnly);
        DataTable ds = new DataTable();
        //#################################################################################
        //  ファイル名が「ID_タイトル.item」になってるつもり
        //  "_"は直接書いちゃってるけど

        ds.Columns.Add("Id");
        ds.Columns.Add("Title");
        ds.Columns.Add("Url");
        foreach (FileInfo item in items)
        {
            DataRow row = ds.NewRow();
            if(item.Name.IndexOf("_") > 0)
            {
                row["Id"] = item.Name.Replace(ITEM_EXT, "").Substring(0,item.Name.IndexOf("_"));
                row["Title"] = item.Name.Replace(ITEM_EXT, "").Substring(item.Name.IndexOf("_")+1);
            }
            else
            {
                row["Id"] = item.Name.Replace(ITEM_EXT, "");
                row["Title"] = "";
            }
            row["Url"] = item.Name.Replace(ITEM_EXT, "");
            ds.Rows.InsertAt(row,0);
        }
        //#################################################################################
        repCategory.DataSource = ds;
        repCategory.DataBind();
        lbDataEdit.Visible = false;
    }
    /// <summary>
    /// 投稿表示
    /// </summary>
    /// <param name="id">表示するアイテムID</param>
    private void ShowData(string id)
    {
        lPageTitle.Text = "投稿表示";
        Item item = new Item(dataDirPath, id);
        lDataTitle.Text = item.ID + ":" + item.Title;
        lDataContent.Text = item.Content.Replace("\n","<br />");
        lDataName.Text = item.Name;
        lDataDate.Text = string.IsNullOrEmpty(item.UpdateDate) ? item.CreateDate : item.UpdateDate;
        lbDataEdit.CommandArgument = item.ID;
        lbDataEdit.Visible = true;
    }
    /// <summary>入力内容をクリア</summary>
    private void ClearWrite()
    {
        tbTitle.Text = "";
        tbContent.Text = "";
        tbName.Text = "";
        tbPassword.Text = "";
        hfID.Value = "";
    }
    /// <summary>
    /// TODO カテゴリー追加
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void OnClickAddCategory(object sender, EventArgs e)
    {
        hfID.Value = "";
    }
    /// <summary>
    /// 投稿追加画面へ遷移
    /// </summary>
    void OnClickAddData(object sender, EventArgs e)
    {
        hfID.Value = "";
        lPageTitle.Text = "投稿";
        mvMain.SetActiveView(vWrite);
    }
    /// <summary>
    /// 投稿保存
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void OnClickCreateData(object sender, EventArgs e)
    {
        // 入力データを反映
        Item item = new Item(dataDirPath, hfID.Value);
        item.Title = tbTitle.Text;
        item.Content = tbContent.Text;
        item.Name = tbName.Text;
        item.Password = tbPassword.Text;
        item.ID = hfID.Value;
        item.IP = Request.UserHostAddress;
        if (!item.Store())
        {
            // Response.Write(" 保存失敗 ");
            // Response.End();
        }
        
        // 入力欄をクリア
        ClearWrite();
        ShowList(dataDirPath);
        ShowData(item.ID);
        mvMain.SetActiveView(vShow);
    }
    /// <summary>
    /// キャンセルボタン押下
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void OnClickCancel(object sender, EventArgs e)
    {
        ClearWrite();
        ShowList(dataDirPath);
        mvMain.SetActiveView(vShow);
    }
    /// <summary>
    /// 投稿表示ボタン押下
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void OnClickView(object sender, CommandEventArgs e)
    {
        string id = Convert.ToString(e.CommandArgument);
        ShowData(id);
    }
    /// <summary>
    /// 投稿編集ボタン押下
    /// </summary>
    void OnClickEdit(object sender, CommandEventArgs e)
    {
        string id = Convert.ToString(e.CommandArgument);
        Session.Add("NextView", vWrite);
        Session.Add("NextID", id);
        mvMain.SetActiveView(vAuth);
    }
    /// <summary>
    /// 認証ボタン押下
    /// </summary>
    void OnClickAuth(object sender, EventArgs e){
        
        View nextView = (View)Session["NextView"];
        bool AuthCorrect = false;
        if (nextView.ID == vWrite.ID)
        {
            nextView = vWrite;
            string id = (string)Session["NextID"];
            Item item = new Item(dataDirPath,id);
            if (tbAuthPass.Text == item.Password)
            {
                hfID.Value = item.ID;
                tbTitle.Text = item.Title;
                tbContent.Text = item.Content;
                tbName.Text = item.Name;
                tbPassword.Text = item.Password;
                lCreateDate.Text = item.CreateDate;
                lCreateIP.Text = item.CreateIP;
                lUpdateDate.Text = item.UpdateDate;
                lUpdateIP.Text = item.UpdateIP;
                AuthCorrect = true;
            }
            tbAuthPass.Text = "";
        }
        if (AuthCorrect)
        {
            lAuthMessage.Text = "";
            mvMain.SetActiveView(nextView);
        }
        else
        {
            lAuthMessage.Text = "パスワードが違います";
        }
    }
    /// <summary>
    /// 投稿データクラス
    /// </summary>
    public class Item 
    {
        DataTable table = null;
        private DataRow row = null;
        private string ip;
        private string path;
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="path"></param>
        /// <param name="id"></param>
        public Item(string path, string id)
        {
            this.path = path;
            table = CreateDataTable();
            //#################################################################################
            //  エラーはあんまり考えてない
            //  そのIDで始まるファイルは１つだろうと
            
	        DirectoryInfo di = new DirectoryInfo(path);
	        FileInfo[] files = di.GetFiles(id + "*" + ITEM_EXT, SearchOption.TopDirectoryOnly);
            FileInfo info = new FileInfo(path + @"\" + files[0].Name);
            //#################################################################################

//            FileInfo info = new FileInfo(path + "\\" + id + ITEM_EXT);
            if (info.Exists)
            {
                // 既存データ
                using (FileStream fs = info.OpenRead())
                {
                    table.ReadXml(fs);
                    row = table.Rows[0];
                }
            }
            else
            {
                // 新規データ
                row = table.NewRow();
            }
        }
        private DataTable CreateDataTable()
        {
            DataTable table = new DataTable();
            table.TableName = "Item";
            table.Columns.Add("ID");
            table.Columns.Add("Content");
            table.Columns.Add("Title");
            table.Columns.Add("Name");
            table.Columns.Add("Password");
            table.Columns.Add("CreateDate");
            table.Columns.Add("CreateIP");
            table.Columns.Add("UpdateDate");
            table.Columns.Add("UpdateIP");
            return table;
        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <returns></returns>
        public bool Store()
        {
            string filePath = null;
            FileMode openMode;
            if (string.IsNullOrEmpty((string)row["ID"]))
            {
                // 新規
            //#################################################################################
            //  こういうやりかたが良いのかどうなのか分からんけど

                row["ID"] = START_ID;
                DirectoryInfo info = new DirectoryInfo(path);
                FileInfo[] files = info.GetFiles(row["ID"] + "*" + ITEM_EXT, SearchOption.TopDirectoryOnly);
                while (files.Length>0)
                {
                    row["ID"] = ((int)(Convert.ToInt32(row["ID"]) + 1)).ToString(START_ID);
                    files = info.GetFiles(row["ID"] + "*" + ITEM_EXT, SearchOption.TopDirectoryOnly);
                }
                filePath = path + @"\" + row["ID"] + "_" + row["Title"] + ITEM_EXT;

//                while (File.Exists(filePath))
//                {
//                    row["ID"] = ((int)(Convert.ToInt32(row["ID"]) + 1)).ToString(START_ID);
//                    filePath = path + @"\" + row["ID"] + ITEM_EXT;
//                }
            //#################################################################################
                row["CreateDate"] = DateTime.Now.ToString("yyyy/MM/dd HH:MM:ss");
                row["CreateIP"] = ip;
                openMode = FileMode.CreateNew;
            }
            else
            {
                // 更新

            //#################################################################################
            //  IDがあるとき、そのIDはあるものと考えて

                DirectoryInfo info = new DirectoryInfo(path);
                FileInfo[] files = info.GetFiles(row["ID"] + "*" + ITEM_EXT, SearchOption.TopDirectoryOnly);
                filePath = path + @"\" + files[0].Name;
            //#################################################################################

                row["UpdateDate"] = DateTime.Now.ToString("yyyy/MM/dd HH:MM:ss");
                row["UpdateIP"] = ip;
                openMode = FileMode.Truncate;
            }
            // 書き込み
            FileInfo info2 = new FileInfo(filePath);
            try
            {
                using (FileStream fs = info2.Open(openMode, FileAccess.ReadWrite, FileShare.Read))
                {
                    if (table.Rows.Count == 0)
                    {
                        table.Rows.Add(row);
                    }
                    table.WriteXml(fs);
                }
                return true;
            }
            catch(Exception ex)
            {
                throw new Exception("保存失敗", ex);
                //return false;
            }
        }
        
        #region IData メンバ
        /// <summary>タイトル</summary>
        public string Title {
            get{ return Convert.ToString(row["Title"]); }
            set{ row["Title"] = value; }
        }
        /// <summary>ID</summary>
        public string ID
        {
            get{ return Convert.ToString(row["ID"]); }
            set{ row["ID"] = value; }
        }
        /// <summary>内容</summary>
        public string Content
        {
            get{ return Convert.ToString(row["Content"]); }
            set{ row["Content"] = value; }
        }
        public string Name
        {
            get{ return Convert.ToString(row["Name"]); }
            set{ row["Name"] = value; }
        }
        public string Password
        {
            get{ return Convert.ToString(row["Password"]); }
            set{ row["Password"] = value; }
        }
        public string IP
        {
            set{ ip = value; }
        }
        public string CreateIP
        {
            get{ return Convert.ToString(row["CreateIP"]); }
        }
        public string CreateDate
        {
            get{ return Convert.ToString(row["CreateDate"]); }
        }
        public string UpdateIP
        {
            get{ return Convert.ToString(row["UpdateIP"]); }
        }
        public string UpdateDate
        {
            get{ return Convert.ToString(row["UpdateDate"]); }
        }
        #endregion
    }

</script>
